import * as ysHelper from 'ys-helper'
import * as Excel from 'exceljs'

const setDefaultRow = (row: Excel.Row) => {
  row.height = 28
  row.eachCell({ includeEmpty: true }, (cell: any, colNumber) =>
    cell.border = {
      top: { style: 'thin' },
      left: { style: 'thin' },
      bottom: { style: 'thin' },
      right: { style: 'thin' }
    })
  row.alignment = {
    vertical: 'middle',
    horizontal: 'center',
    wrapText: true
  }
}

interface ExportParams {
  /** 标题 */
  fnameText: string
  /** 表头 */
  dataHeaders: string[]
  /** 提示信息 */
  filterText?: string
  /** 列表长度 */
  closWidth?: number[],
  /** 列对应行的key */
  closKeyName?: string[],
  /** 列数据 */
  rowItem: any[],
  /** 添加row前发生 */
  setRow?: (rowData: any, sheet: Excel.Worksheet, rowNumber: number) => any
}

/** excel 导出 */
export default async function exportExcelSV(req: any, res: any, next: any, {
  fnameText,
  dataHeaders,
  filterText = '',
  closWidth = [],
  closKeyName,
  rowItem,
  setRow
}: ExportParams) {
  /** 设置excel */
  let workbook = new Excel.Workbook()
  let sheet = workbook.addWorksheet(fnameText)
  workbook.creator = 'ys'
  workbook.lastModifiedBy = 'ys'

  let char = String.fromCharCode(dataHeaders.length + 64) //转换为对应字母 1->A 2->B
  sheet.mergeCells('A1', `${char}1`);
  /** 首行表题 */
  let titltCell = sheet.getCell('A1')
  titltCell.value = fnameText
  titltCell.alignment = {
    vertical: 'middle',
    horizontal: 'center'
  }
  titltCell.font = {
    size: 16
  }
  sheet.getRow(1).height = 40

  /** 表头行数 */
  let headerRowNum = 2

  if (filterText) {
    ++headerRowNum
    let filterRow = sheet.getRow(2)
    filterRow.values = [filterText]
    filterRow.height = 28
    filterRow.alignment = {
      vertical: 'middle'
    }
    sheet.mergeCells('A2', `${char}2`);
  }

  /** 表头 */
  let headerRow = sheet.getRow(headerRowNum)
  headerRow.values = dataHeaders
  let headerColumns: any = []
  dataHeaders.forEach((item, index) => {
    headerColumns.push({
      key: closKeyName ? closKeyName[index] : undefined,
      width: closWidth[index] || 20
    })
  })
  sheet.columns = headerColumns
  headerRow!.height = 24
  headerRow!.alignment = {
    vertical: 'middle'
  }
  setDefaultRow(headerRow)

  rowItem.forEach((item: any, index: number) => {
    if (setRow) {
      item = setRow(item, sheet, index + headerRowNum + 1)
    }
    if (item) {
      let row = sheet.addRow(item)
      setDefaultRow(row)
    }
  })


  try {
    let result = await workbook.xlsx.writeBuffer()
    res.setHeader('Content-Type', 'application/vnd.openxmlformats;charset=utf-8')
    let disposition = ysHelper.tools.createDownloadDisposition(req, `${fnameText}.xlsx`)
    res.setHeader('Content-Disposition', disposition)
    res.end(result, 'binary')
    return
  } catch (e) {
    next(e)
  }
}